#include <boost/beast.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <string>

namespace beast = boost::beast;  // from <boost/beast.hpp>
namespace http = beast::http;    // from <boost/beast/http.hpp>
namespace net = boost::asio;     // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp;// from <boost/asio/ip/tcp.hpp>

// 处理一个HTTP连接的会话类
class HttpSession : public std::enable_shared_from_this<HttpSession>
{
private:
    tcp::socket socket_;
    beast::flat_buffer buffer_;
    http::request<http::string_body> req_;

public:
    // 构造函数，接管socket
    explicit HttpSession(tcp::socket socket) : socket_(std::move(socket)) {}

    void run()
    {
        do_read();
    }

private:
    // 读取HTTP请求
    void do_read()
    {
        auto self(shared_from_this());

        // 读取请求
        http::async_read(socket_, buffer_, req_,
                         [self](beast::error_code ec, std::size_t bytes_transferred) {
                             boost::ignore_unused(bytes_transferred);

                             // 发生错误时关闭连接
                             if (ec)
                             {
                                 if (ec != http::error::end_of_stream)
                                     std::cerr << "read error: " << ec.message() << std::endl;
                                 return;
                             }

                             // 处理请求并发送响应
                             self->handle_request();
                         });
    }
    void handle_request()
    {
        // 创建响应
        http::response<http::string_body> res{http::status::ok, req_.version()};
        res.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        res.set(http::field::content_type, "text/html");
        res.keep_alive(req_.keep_alive());

        // 根据请求路径返回不同内容
        if (req_.target() == "/")
        {
            res.body() = "<html><head><title>Boost.Beast Server</title></head>"
                         "<body><h1>Welcome to Boost.Beast HTTP Server</h1>"
                         "<p>Request path: /</p></body></html>";
        }
        else if (req_.target() == "/about")
        {
            res.body() = "<html><head><title>About</title></head>"
                         "<body><h1>About</h1>"
                         "<p>This is a simple HTTP server using Boost.Beast</p></body></html>";
        }
        else
        {
            // 处理404未找到
            res.result(http::status::not_found);
            res.body() = "<html><head><title>Not Found</title></head>"
                         "<body><h1>404 Not Found</h1></body></html>";
        }

        res.prepare_payload();

        auto self(shared_from_this());

        // 发送响应
        http::async_write(socket_, res,
                          [self](beast::error_code ec, std::size_t bytes_transferred) {
                              boost::ignore_unused(bytes_transferred);

                              if (ec)
								  std::cerr << "write error: " << ec.message() << std::endl;
                              if (!ec && self->req_.keep_alive())
                              {
                                  self->do_read();
                              }
                          });
    }
};

// 接受新连接的 acceptor 类
class HttpListener : public std::enable_shared_from_this<HttpListener>
{
private:
    tcp::acceptor acceptor_;

public:
    // 构造函数
    HttpListener(net::io_context &ioc, tcp::endpoint endpoint)
        : acceptor_(ioc)
    {
        beast::error_code ec;

        // 打开 acceptor
        acceptor_.open(endpoint.protocol(), ec);
        if (ec)
        {
            fail(ec, "open");
            return;
        }

        // 允许地址重用
        acceptor_.set_option(net::socket_base::reuse_address(true), ec);
        if (ec)
        {
            fail(ec, "set_option");
            return;
        }

        // 绑定地址
        acceptor_.bind(endpoint, ec);
        if (ec)
        {
            fail(ec, "bind");
            return;
        }

        // 开始监听
        acceptor_.listen(net::socket_base::max_listen_connections, ec);
        if (ec)
        {
            fail(ec, "listen");
            return;
        }
    }

    // 开始接受连接
    void run()
    {
        do_accept();
    }

private:
    // 报告错误
    static void fail(beast::error_code ec, char const *what)
    {
        std::cerr << what << ": " << ec.message() << std::endl;
    }

    // 接受新连接
    void do_accept()
    {
        //  acceptor 会生成新的socket
        acceptor_.async_accept(
                net::make_strand(acceptor_.get_executor()),
                beast::bind_front_handler(
                        &HttpListener::on_accept,
                        shared_from_this()));
    }

    // 处理接受的连接
    void on_accept(beast::error_code ec, tcp::socket socket)
    {
        if (ec)
        {
            fail(ec, "accept");
        }
        else
        {
            // 创建会话并运行
            std::make_shared<HttpSession>(std::move(socket))->run();
        }

        // 接受下一个连接
        do_accept();
    }
};

int main(int argc, char *argv[])
{
    try
    {
        // 设置监听端口
        unsigned short port = 8080;
        if (argc == 2)
        {
            port = static_cast<unsigned short>(std::atoi(argv[1]));
        }

        // 用于运行I/O的上下文
        net::io_context ioc{1};

        // 创建并运行监听器
        auto const address = net::ip::make_address("0.0.0.0");
        auto const endpoint = tcp::endpoint{address, port};

        std::make_shared<HttpListener>(ioc, endpoint)->run();

        std::cout << "Server is running on http://localhost:" << port << std::endl;

        // 运行I/O服务
        ioc.run();
    }
    catch (std::exception const &e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}
